//
// Created by Suzhen on 2017/2/24.
//

#include "IOBuffer.h"

#include "boost/fiber/future.hpp"

USING_ORION_V2

IOBuffer::IOBuffer(const RawDataType *bf, size_t sz, bool transfer)
        : transfer(transfer),
          len(sz),
          index(0),
          buf(transfer ? bf : new RawDataType[sz]),
          completePromise_(new Promise<bool>()) {
    if (!transfer) {
        std::copy(bf, bf + sz, const_cast<RawDataType *>(buf));
    }
}

IOBuffer::IOBuffer(IOBuffer &&other)
        : transfer(other.transfer),
          len(other.len),
          index(other.index),
          buf(other.buf),
          completePromise_(other.completePromise_) {
    other.buf = nullptr;
    other.len = 0;
    other.index = 0;
    other.completePromise_ = nullptr;
}

IOBuffer &IOBuffer::operator=(IOBuffer &&other) {
    if (this == &other) {
        return *this;
    }
    transfer = other.transfer;
    len = other.len;
    index = other.index;
    buf = other.buf;
    completePromise_ = other.completePromise_;
    //
    other.len = 0;
    other.index = 0;
    other.buf = nullptr;
    other.completePromise_ = nullptr;
    return *this;
}

IOBuffer::~IOBuffer() {
#ifdef ENABLE_LOG
    LOG_I << "~ IOBuffer";
#endif
    //尝试释放buf ,如果buf不是被转移到Item中,则什么都不做
    //返回 , 没有写完
    if (completePromise_ && !completePromise_->hasValue()) {
        completePromise_->setValue(NO);
    }
    //释放sendPromise
    delete completePromise_;
    //如果是转移的buf , 则不需要我们进行释放(由用户管理)
    //同时buf 不能为 nullptr
    if (transfer || buf == nullptr) {
        return;
    }
    delete[] buf;
    len = 0;
    index = 0;
}

Future<bool> IOBuffer::getCompleteFuture() {
    return completePromise_->getFuture();
}

size_t IOBuffer::getLen() const {
    return len;
}

size_t IOBuffer::getIndex() const {
    return index;
}

const RawDataType *IOBuffer::getBuf() const {
    return buf;
}

void IOBuffer::releaseBuf() {
    if (transfer) {
        return;
    }
    transfer = true;
}

